_package("alz.gesture");

_import("alz.gesture.Gesture");

/**
 * 拿捏手势
 */
_class("Pinch", Gesture, function(){
	this.handles = ["pinchstart", "pinch", "pinchend"];
	this.touches = 2;
	this._init = function(config){
		_super._init.apply(this, arguments);
	};
	this.onTouchStart = function(ev){
		if(runtime.isTouch && ev.targetTouches.length >= 2){
			this.lock("swipe", "scroll", "scrollstart", "scrollend", "touchmove", "touchend", "touchstart", "tap", "tapstart", "taphold", "tapcancel", "doubletap");
			this.pinching = true;
			var targetTouches = ev.targetTouches,
				firstTouch = this.firstTouch = targetTouches[0],
				secondTouch = this.secondTouch = targetTouches[1];
			this.previousDistance = this.startDistance = this.getDistance();
			this.previousScale = 1;
			this.fire("pinchstart", ev, {
				distance: this.startDistance,
				scale: this.previousScale
			});
		}else if(this.pinching){
			this.unlock("swipe", "scroll", "scrollstart", "scrollend", "touchmove", "touchend", "touchstart", "tap", "tapstart", "taphold", "tapcancel", "doubletap");
			this.pinching = false;
		}
	};
	this.onTouchMove = function(ev){
		if(this.pinching){
			this.fire("pinch", ev, this.getPinchInfo());
		}
	};
	this.onTouchEnd = function(ev){
		if(this.pinching){
			this.fire("pinchend", ev, this.getPinchInfo());
		}
	};
	this.getPinchInfo = function(){
		var distance = this.getDistance();
		var scale = distance / this.startDistance;
		var firstTouch = this.firstTouch;
		var secondTouch = this.secondTouch;
		var info = {
			"scale"                : scale,
			"deltaScale"           : scale - 1,
			"previousScale"        : this.previousScale,
			"previousDeltaScale"   : scale - this.previousScale,
			"distance"             : distance,
			"deltaDistance"        : distance - this.startDistance,
			"startDistance"        : this.startDistance,
			"previousDistance"     : this.previousDistance,
			"previousDeltaDistance": distance - this.previousDistance,
			"firstTouch"           : firstTouch,
			"secondTouch"          : secondTouch,
			"firstPageX"           : firstTouch.pageX,
			"firstPageY"           : firstTouch.pageY,
			"secondPageX"          : secondTouch.pageX,
			"secondPageY"          : secondTouch.pageY,
			// The midpoint between the touches is (x1 + x2) / 2, (y1 + y2) / 2
			"midPointX"            : (firstTouch.pageX + secondTouch.pageX) / 2,
			"midPointY"            : (firstTouch.pageY + secondTouch.pageY) / 2
		};
		this.previousScale = scale;
		this.previousDistance = distance;
		return info;
	};
	this.getDistance = function(){
		return Math.sqrt(
			Math.pow(Math.abs(this.firstTouch.pageX - this.secondTouch.pageX), 2) +
			Math.pow(Math.abs(this.firstTouch.pageY - this.secondTouch.pageY), 2)
		);
	};
});